#ifndef GAMEENGINE_GEOMETRY_POINT3D_H
#define GAMEENGINE_GEOMETRY_POINT3D_H

#include <GameEngine/Geometry/geometry_settings.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

template <class T> class Vector3d;

namespace Point3D {
	//! Coordinate index for a three-dimensional point
	enum Index {
		//! First coordinate (aka 'x')
		First = 0,
		//! Second coordinate (aka 'y')
		Second = 1,
		//! Third coordinate (aka 'z')
		Third = 2
	};
}



//! Class used to represent 3D points
/*!
 @note A 3D point is made of three coordinates, typically
       named x, y and z. The coordinates are of type T,
	   which allows client code to choose the level of
	   precision (typically, T will be either float or
	   double)
 @todo Setup unit tests
 @sa The Point2d class that handles 2D points, and the Vector3d class that
     handles 3D vectors.
 */
template <class T>
class Point3d {

public:
	Point3d();
	Point3d(const T& x, const T& y, const T& z);
	Point3d(const Point3d& rhs);
	template <class R> Point3d(const Point3d<R>& rhs);
	virtual ~Point3d();
	Point3d& operator=(const Point3d& rhs);

	T& x();
	const T& x() const;
	T& y();
	const T& y() const;
	T& z();
	const T& z() const;

	T& operator[](Point3D::Index index);
	const T& operator[](Point3D::Index index) const;

	double get_distance(const Point3d& rhs) const;
	T get_square_distance(const Point3d& rhs) const;

protected:
	//! Point coordinates
	T coordinates_[3];
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Location/point3d.hpp>

#endif
